define(function (require, exports) {
    var base = require("customize/ui/base");
    var jsonUtil = require("customize/util/json");
    var form = require("customize/bootstrap/form");
    var validator = require("customize/bootstrap/validator");

    var defaultApiOptions = {
        start: 0,
        limit: parseInt(localStorage.getItem("gridLimit")) || 10
    };

    var defaultGridOptions = {
        pageRange: 6,
        editPrefixTitle: "编辑",
        targetForm: "#form",
        loadingHTML: '<div class="progress progress-striped active" style="width:50%;margin:auto;">' +
        '<div class="bar" style="width:100%;"></div></div>',
        beforeRenderRow: false,//渲染表格每行前触发，可以对该行的数据进行处理
        afterRenderRow: false,//渲染表格每行后触发
        beforeFillForm: false,//填充数据到表单前触发，比如展现或者隐藏标签等
        afterFillForm: false, //填充数据到表单后触发
        beforeClickAddBtn: false,
        afterClickAddBtn: false,
        beforeDeleteRow: false,
        afterDeleteRow: false,
        checkbox: true,
        idField: 'id'
    };

    var renderRow = function (target, data) {
        var apiOptions = target.data("apiOptions"),
            gridOptions = target.data("gridOptions"),
            start = apiOptions.start,
            rows = data.rows,
            rowNum = rows.length,
            rowTemplate = target.data("rowTemplate"),
            trs = [];

        if(gridOptions.checkbox) {
            var checkAll = '<th><input type="checkbox" id="checkAll" onclick="checkAll(' + target + ')"/></th>';
            if(target.find("thead tr #checkAll").length < 1) {
                target.find("thead tr").first().prepend(checkAll);
            }
        }

        for (var i = 0; i < rowNum; i++) {
            var row = rows[i];
            if (gridOptions.beforeRenderRow) {
                gridOptions.beforeRenderRow(row);
            }

            var replacement = function (word) {
                var columnName = word.substring(2, word.length - 1);
                if (columnName == 'rowIndex') {
                    return start + i + 1;
                }
                if (columnName == 'pageRowIndex') {
                    return i;
                }
                var result = jsonUtil.getFromPath(row, columnName);
                return (result == undefined || result == null) ? "" : result;
            };

            var id = row[gridOptions.idField] ? row[gridOptions.idField] : '';
            var checkbox = '<td><input type="checkbox" id="' + id + '"/></td>';

            var appendCheckbox = function(tr) {
                return tr + checkbox;
            };

            var tr = rowTemplate.replace(/\$\(.*?\)/g, replacement);
            if(gridOptions.checkbox) {
                tr = tr.replace(/<tr.?>/, appendCheckbox);
            }

            trs.push(tr);
        }

        target.find("tbody").html(trs.join(""));

        if (gridOptions.afterRenderRow) {
            gridOptions.afterRenderRow(row);
        }
    };

    var validateForm = function (target) {
        var apiOptions = target.data("apiOptions"),
            gridOptions = target.data("gridOptions"),
            targetForm = gridOptions.targetForm;
        validator.validate(targetForm, {
            preventSubmit: true,
            submitSuccess: function ($form, event) {
                form.submit(targetForm, apiOptions.saveApi,
                    function (request) {
                        return request;
                    },
                    function (response) {
                        alert(response.description);
                        exports.filter(target);
                    },
                    function (response) {
                        alert(response.description);
                    }
                );
                event.preventDefault();
            }
        });
    };

    var renderPaginationBar = function (target, data) {
        var apiOptions = target.data("apiOptions"),
            gridOptions = target.data("gridOptions"),
            start = apiOptions.start,
            limit = apiOptions.limit,
            pageRange = gridOptions.pageRange,
            rowNum = data.rows.length,
            totalRecord = data.total || data.rows.length,
            totalPagerNum = Math.ceil((data.total || data.rows.length || 0) / limit),
            showTotalPagerNum = totalPagerNum == 0 ? 1 : totalPagerNum,
            current = parseInt(start / limit) + 1,
            firstAndPreviousClass = current == 1 ? 'disabled' : '',
            nextAndLastClass = current == showTotalPagerNum ? 'disabled' : '',
            lastPager = Math.min(current < Math.ceil(pageRange / 2) ? pageRange : current + parseInt(pageRange / 2), showTotalPagerNum),
            startPager = Math.max(lastPager - (pageRange - 1), 1),
            pagers = [];


        for (var j = startPager; j <= lastPager; j++) {
            pagers.push(
                '<li class="' + (current == j ? ' active' : '') + '">' +
                    '<a href="#" class="page" page="' + j + '">' + j + '</a>' +
                '</li>'
            );
        }

        var columnNum = gridOptions.checkbox ? target.data("columnNum") + 1 : target.data("columnNum");
        target.find("tfoot").html(
            '<tr>' +
                '<td colspan="' + columnNum + '">' +
                    '<div class="row">' +
                        '<div class="col-xs-6 text-left">' +
                            '<nav>' +
                                '<ul class="pagination">' +
                                    '<li class="' + firstAndPreviousClass + '">' +
                                        '<a href="#" class="firstPage">' +
                                            '<span aria-hidden="true">&laquo;</span>' +
                                        '</a>' +
                                    '</li>' +
                                    '<li class="' + firstAndPreviousClass + '">' +
                                        '<a href="#" class="previousPage">' +
                                            '<span aria-hidden="true">&lt;</span>' +
                                        '</a>' +
                                    '</li>' +
                                    pagers.join("") +
                                    '<li class="' + nextAndLastClass + '">' +
                                        '<a href="#" class="nextPage">' +
                                            '<span aria-hidden="true">&gt;</span>' +
                                        '</a>' +
                                    '</li>' +
                                    '<li class="' + nextAndLastClass + '">' +
                                        '<a href="#" class="lastPage">' +
                                            '<span aria-hidden="true">&raquo;</span>' +
                                        '</a>' +
                                    '</li>' +
                                '</ul>' +
                            '</nav>' +
                        '</div>' +
                        '<div class="col-xs-6 text-right" style="margin-top:25px">' +
                            '<small>第' + current + '/' + showTotalPagerNum + '页，每页' +
                            '<select class="grid-limit" style="width:60px;">' +
                                '<option value="10">10</option>' +
                                '<option value="20">20</option>' +
                                '<option value="50">50</option>' +
                            '</select>' +
                            '条，共' + totalRecord + '条数据，显示' + ((current - 1) * limit + 1) + '-' + ((current - 1) * limit + rowNum) + '条</small>' +
                        '</div>' +
                    '</div>' +
                '</td>' +
            '</tr>'
        );

        target.find("tfoot .grid-limit").val(limit);
        target.show();
    };

    var placeholderRowHTML = function (target, content) {
        return '<tr><td style="text-align:center;padding:20px;border-bottom:none;" colspan="' +
            target.data("columnNum") + '">' + content + '</td></tr>';
    };

    exports.filter = function (target, apiOptions) {
        target = base.jq(target);

        target.find("tbody").html(placeholderRowHTML(target, defaultGridOptions.loadingHTML));

        base.filter(target, "grid.n", function (url) {
            $.post(url, null, function (data) {
                target.data("data", data);
                renderRow(target, data);
                renderPaginationBar(target, data);
            }, "json");
        }, apiOptions);
    };

    var bindPaginationEvent = function (target) {
        $(target).on("click", ".firstPage", function () {
            if ($(this).parent().hasClass("disabled")) {
                return;
            }
            exports.filter(target, {start: 0});
        });

        $(target).on("click", ".nextPage", function () {
            if ($(this).parent().hasClass("disabled")) {
                return;
            }
            var option = target.data("apiOptions");
            exports.filter(target, {start: option.start + option.limit});
        });

        $(target).on("click", ".previousPage", function () {
            if ($(this).parent().hasClass("disabled")) {
                return;
            }

            var option = target.data("apiOptions");
            exports.filter(target, {start: option.start - option.limit});
        });

        $(target).on("click", ".lastPage", function () {
            if ($(this).parent().hasClass("disabled")) {
                return;
            }

            var option = target.data("apiOptions");
            var data = target.data("data");
            exports.filter(target, {start: (Math.ceil(data.total / option.limit) - 1) * option.limit});
        });

        $(target).on("click", ".page", function () {
            var option = target.data("apiOptions");
            exports.filter(target, {start: (parseInt($(this).attr("page")) - 1) * option.limit});
        });

        $(target).on("change", "tfoot .grid-limit", function () {
            var limit = $(this).val();
            defaultApiOptions.limit = limit;
            localStorage.setItem("gridLimit", limit);
            exports.filter(target);
        });
    };

    var bindRowEvent = function (target) {
        $(target).parent().on("click", ".grid-edit", function () {
            var option = target.data("gridOptions");
            var targetForm = base.jq(option.targetForm);
            targetForm.find(".grid-prefix-title").text(option.editPrefixTitle);

            var rowData = target.data("data").rows[$(this).attr("pageRowIndex")];
            if (option.beforeFillForm) {
                option.beforeFillForm(rowData);
            }

            targetForm.find("ul.nav a:first").tab("show");

            form.fill(targetForm, rowData);

            if (option.afterFillForm) {
                option.afterFillForm(rowData);
            }
        });


        $(target).parent().on("click", ".grid-delete", function () {
            if (!confirm("确定删除该记录？")) return;
            var option = target.data("gridOptions");

            var rowData = target.data("data").rows[$(this).attr("pageRowIndex")];

            var param;

            if (option.beforeDeleteRow) {
                param = option.beforeDeleteRow(rowData);
            }

            var apiOptions = target.data("apiOptions");
            form.post(apiOptions.deleteApi, param || rowData, null,
                function (response) {
                    alert(response.description);
                    if (option.afterDeleteRow) {
                        option.afterDeleteRow();
                    }
                    exports.filter(target, {start: 0});
                    form.fill(option.targetForm, {});
                }, function (response) {
                    alert(response.description);
                });


        });
    };

    var bindAddButtonEvent = function (target) {
        $(target).parent().on("click", ".grid-add", function () {
            var option = target.data("gridOptions");
            var targetForm = base.jq(option.targetForm);

            if (option.beforeClickAddBtn) {
                option.beforeClickAddBtn();
            }

            form.fill(targetForm, {});

            if (option.afterClickAddBtn) {
                option.afterClickAddBtn();
            }
            form.focusFirstValidElement(targetForm);
        });
    };

    var bindSearchEvent = function (target) {
        $(document).on("keyup", "input[name]", function (event) {
            event = event || window.event;
            if (event.keyCode == 13 || event.charCode == 13) {
                exports.filter(target, {start: 0});
            }
        });

        $(target).on("click", ".datagrid-btn-search", function () {
            exports.filter(target, {start: 0});
        })
    };

    exports.init = function (target, apiOptions, gridOptions) {
        if (!apiOptions) {
            alert("api参数为空");
            return null;
        }

        target = base.jq(target);

        apiOptions.filterRegion = base.jq(apiOptions.filterRegion || target, false);

        target.data("apiOptions", $.extend(defaultApiOptions, apiOptions));

        $.extend(defaultGridOptions, gridOptions);
        target.data("gridOptions", defaultGridOptions);
        target.data("columnNum", target.find("tbody tr:eq(0) td").size());
        target.data("rowTemplate", target.find("tbody").html());

        //bindSearchEvent(target);
        //bindAddButtonEvent(target);
        //bindRowEvent(target);
        bindPaginationEvent(target);
        //validateForm(target);

        exports.filter(target, apiOptions);
    };

    var checkAll = function(target) {
        target.find("tbody tr")
    };
});
